//
//  NSDate+Formatter.m
//  testObjc
//
//  Created by bianruifeng on 2020/7/1.
//  Copyright © 2020 test. All rights reserved.
//

#import "NSDate+Formatter.h"
#import "NSDateComponents+Category.h"


@implementation NSDate (Formatter)
//今天零点的时间
- (NSDate *)zeroOfDate {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:self];
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    
    // components.nanosecond = 0 not available in iOS
    NSTimeInterval ts = (double)(int)[[calendar dateFromComponents:components] timeIntervalSince1970];
    return [NSDate dateWithTimeIntervalSince1970:ts];
}
- (NSString *)formatDateString {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    NSString *currentTimeString = [formatter stringFromDate:self];
    return currentTimeString;
}

//日期的年月日
- (NSInteger)getYear {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"YYYY"];
    NSString *currentTimeString = [formatter stringFromDate:self];
    return currentTimeString.integerValue;
}
- (NSInteger)getMonth {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM"];
    NSString *currentTimeString = [formatter stringFromDate:self];
    return currentTimeString.integerValue;
}
- (NSInteger)getDay {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"dd"];
    NSString *currentTimeString = [formatter stringFromDate:self];
    return currentTimeString.integerValue;
}


//当前时间
+ (NSString *)currentDateString {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
    NSDate *datenow = [NSDate date];
    NSString *currentTimeString = [formatter stringFromDate:datenow];
    return currentTimeString;
}

+ (NSString *)formatDate:(NSString *)dateStr withFormatString:(NSString *)formatStr {
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"MMM dd, yyyy hh:mm:ss aa"];
    [dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]];
    [dateFormat setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
    NSDate *date =[dateFormat dateFromString:dateStr];
    NSDateFormatter* dateFormat2 = [[NSDateFormatter alloc] init];
    //    2018-04-16 20:14:13 formatStr
    [dateFormat2 setDateFormat:formatStr];
    NSString *publishtimeStr = [dateFormat2 stringFromDate:date];
    return publishtimeStr;
}


-(NSInteger)year
{
    NSDateComponents *components = [NSDateComponents dateComponentsFromDate:self];
    return components.year;
}
- (NSInteger) month
{
    NSDateComponents *components =  [NSDateComponents dateComponentsFromDate:self];
    return components.month;
}

- (NSInteger) day
{
    NSDateComponents *components =  [NSDateComponents dateComponentsFromDate:self];
    return components.day;
}

- (NSInteger) hour
{
    NSDateComponents *components =  [NSDateComponents dateComponentsFromDate:self];
    return components.hour;
}

- (NSInteger) minute
{
    NSDateComponents *components = [NSDateComponents dateComponentsFromDate:self];
    return components.minute;
}

- (NSInteger) seconds
{
    NSDateComponents *components =  [NSDateComponents dateComponentsFromDate:self];
    return components.second;
}

- (NSInteger) weekday
{
    NSDateComponents *components =  [NSDateComponents dateComponentsFromDate:self];
    return components.weekday;
}

+(NSDate *)dateWithDateString:(NSString *)dateString
{
    NSDate *date = nil;
    date = [self dateWithFormat_yyyy_MM_dd_HH_mm_ss_string:dateString];
    if(date) return date;
    date = [self dateWithFormat_yyyy_MM_dd_HH_mm_string:dateString];
    if(date) return date;
    date = [self dateWithFormat_yyyy_MM_dd_HH_string:dateString];
    if(date) return date;
    date = [self dateWithFormat_yyyy_MM_dd_string:dateString];
    if(date) return date;
    date = [self dateWithFormat_yyyy_MM_string:dateString];
    if(date) return date;
    return nil;
}
+(NSDate *)dateWithDateStr:(NSString *)dateStr format:(NSString *)format
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:format];
    NSDate *date =[dateFormat dateFromString:dateStr];
    return date;
}
+(NSString *)dateStrWithDate:(NSDate *)date format:(NSString *)format
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:format];
    NSString *dateStr =[dateFormat stringFromDate:date];
    return dateStr;
}


+(NSDate *)dateWithFormat_yyyy_MM_dd_HH_mm_ss_string:(NSString *)string
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *date =[dateFormat dateFromString:string];
    return date;
}

+(NSDate *)dateWithFormat_yyyy_MM_dd_HH_mm_string:(NSString *)string
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm"];
    NSDate *date =[dateFormat dateFromString:string];
    return date;
}

+(NSDate *)dateWithFormat_yyyy_MM_dd_HH_string:(NSString *)string
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH"];
    NSDate *date =[dateFormat dateFromString:string];
    return date;
}

+(NSDate *)dateWithFormat_yyyy_MM_dd_string:(NSString *)string
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd"];
    NSDate *date =[dateFormat dateFromString:string];
    return date;
}

+(NSDate *)dateWithFormat_yyyy_MM_string:(NSString *)string
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM"];
    NSDate *date =[dateFormat dateFromString:string];
    return date;
}

/// 获取今年所有的周
- (NSArray *)getAllWeekDate {
    //闰年2月份是29天
    NSDate *nowDate = [NSDate date];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *comp = [calendar components: NSCalendarUnitWeekday | NSCalendarUnitWeekOfYear fromDate:nowDate];
    // 获取今天是周几 (周一是2，周日是1)
    NSInteger weekDay = [comp weekday];
    //这周是今年的第几周(注意：第一周编号为1不为0)
    NSInteger weekOfYear = [comp weekOfYear];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyyMMdd"];
    NSDate *date = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]];
    //这周的开始和结束时间 （注意：+1 -1 避开临界值）
    NSDate *startdate = [date dateByAddingTimeInterval:24*3600*(2 - weekDay)+1];
    NSDate *enddate = [date dateByAddingTimeInterval:24*3600*(9 - weekDay)-1];
    NSMutableArray *dateArray = [[[NSMutableArray alloc] init] mutableCopy];
    //一年52周  获取一年的所有周一和周日的日期(注意：第一周编号为1不为0)
    for (int i = 1; i <= 52; i++) {
        NSDate *startdate1 = [startdate dateByAddingTimeInterval:24*3600*7*(i-weekOfYear)];
        NSDate *enddate1 = [enddate dateByAddingTimeInterval:24*3600*7*(i-weekOfYear)];
        [dateArray addObject:@[startdate1,enddate1]];
    }
    
    return dateArray;
}

-(NSInteger)weekOfYear
{
    NSDate *showDate = [NSDate date];
    NSCalendar*calendar = [NSCalendar currentCalendar];
    NSDateComponents *comps =[calendar components:(NSCalendarUnitWeekOfYear | NSCalendarUnitWeekday |NSCalendarUnitWeekdayOrdinal) fromDate:showDate];
    NSInteger week = [comps weekOfYear]; // 今年的第几周
    NSInteger weekday = [comps weekday]; // 星期几（注意，周日是“1”，周一是“2”。。。。）
    NSInteger weekdayOrdinal = [comps weekdayOrdinal]; // 这个月的第几周
    return week;
}

/// 获取当前时间若干年、月、日之后的时间
/// @param date 相对于当前时间，指定时差之后的时间
/// @param years 年
/// @param months 月
/// @param days 日
+ (NSDate *)dateWithFromDate:(NSDate *)date years:(NSInteger)years months:(NSInteger)months days:(NSInteger)days{
    NSDate  * latterDate;
    if (date) {
        latterDate = date;
    }else{
        latterDate = [NSDate date];
    }
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute
                                          fromDate:latterDate];
    
    [comps setYear:years];
    [comps setMonth:months];
    [comps setDay:days];
    
    return [calendar dateByAddingComponents:comps toDate:latterDate options:0];
}

+ (NSInteger)numberOfDaysWithFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    NSDateComponents    * comp = [calendar components:NSCalendarUnitDay
                                             fromDate:fromDate
                                               toDate:toDate
                                              options:NSCalendarWrapComponents];
    NSLog(@" -- >>  comp : %@  << --",comp);
    return comp.day;
}

+ (NSString *)checkTheDate:(NSString *)string{
    
    NSDateFormatter *format = [[NSDateFormatter alloc]init];
    [format setDateFormat:@"yyyy-MM-dd"];
    NSDate *date = [format dateFromString:string];
    BOOL isToday = [[NSCalendar currentCalendar] isDateInToday:date];
    NSString *strDiff = nil;
    
    if(isToday) {
        strDiff= [NSString stringWithFormat:@"今天"];
    }
    return strDiff;
}

- (NSString *)weekdayStringWithDate:(NSDate *)date {
    //获取星期几
    NSDateComponents *componets = [[NSCalendar autoupdatingCurrentCalendar] components:NSCalendarUnitWeekday fromDate:date];
    NSInteger weekday = [componets weekday];//1代表星期日，2代表星期一，后面依次
    NSArray *weekArray = @[@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六"];
    NSString *weekStr = weekArray[weekday-1];
    return weekStr;
}

/**
 比较两个日期的大小 0 相等； 1 后者大于前者; -1 前者大于后者
 日期格式请传入：2013-08-05 12:12:12；如果修改日期格式，比如：2013-08-05，则将[df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];修改为[dateformater setDateFormat:@"yyyy-MM-dd"];
 @param aDate 日期A
 @param bDate 日期B
 @return 0 相等； 1 B > A; -1 A > B
 */
+ (NSInteger)compareWithADate:(NSString*)aDate bDate:(NSString*)bDate {
    
    NSInteger value = 0;
    NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];
    [dateformater setDateFormat:@"yyyy-MM-dd"];
    NSDate *dta = [[NSDate alloc] init];
    NSDate *dtb = [[NSDate alloc] init];
    
    dta = [dateformater dateFromString:aDate];
    dtb = [dateformater dateFromString:bDate];
    NSComparisonResult result = [dta compare:dtb];
    if (result == NSOrderedSame) {
        //        相等  aa=0
    }
    else if (result == NSOrderedAscending) {
        //bDate比aDate大
        value = 1;
    }
    else if (result == NSOrderedDescending) {
        //bDate比aDate小
        value = -1;
    }
    
    return value;
}

/**
 获取指定日期的周一 和 周末的日期
 
 @param date 某一日期
 @return @“10.13-10.19”
 */
+ (NSString *)weekTimeForDate:(NSDate *)date {
    
    NSDate *nowDate = date;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *comp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday  fromDate:nowDate];
    // 获取今天是周几
    NSInteger weekDay = [comp weekday];
    // 获取几天是几号
    NSInteger day = [comp day];
    NSLog(@"周几 %ld---- 几号 %ld",(long)weekDay,(long)day);
    
    // 计算当前日期和本周的星期一和星期天相差天数
    long firstDiff,lastDiff;
    //    weekDay = 1; weekDay == 1 == 周日
    if (weekDay == 1) {
        firstDiff = -6;
        lastDiff = 0;
    }
    else {
        firstDiff = [calendar firstWeekday] - weekDay + 1;
        lastDiff = 8 - weekDay;
    }
    NSLog(@"firstDiff: %ld   lastDiff: %ld",firstDiff,lastDiff);
    
    // 在当前日期(去掉时分秒)基础上加上差的天数
    NSDateComponents *baseDayComp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay  fromDate:nowDate];
    
    //获取周一日期
    [baseDayComp setDay:day + firstDiff];
    NSDate *firstDayOfWeek = [calendar dateFromComponents:baseDayComp];
    
    //获取周末日期
    [baseDayComp setDay:day + lastDiff];
    NSDate *lastDayOfWeek = [calendar dateFromComponents:baseDayComp];
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    //    [formatter setDateFormat:@"YYYY年MM月dd日"];
    [formatter setDateFormat:@"MM.dd"];
    NSString *firstDay = [formatter stringFromDate:firstDayOfWeek];
    NSString *lastDay = [formatter stringFromDate:lastDayOfWeek];
    NSLog(@"%@=======%@",firstDay,lastDay);
    NSString *dateStr = [NSString stringWithFormat:@"%@-%@",firstDay,lastDay];
    
    return dateStr;
}

//使用C语言来做日期处理
-(void)testDateFormatterInC:(NSInteger)times {
    NSString *string = @"";
    NSDate *date;
    time_t timeInterval;
    char buffer[80];
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    for (int i=0; i<times; i++) {
        date = [NSDate dateWithTimeIntervalSince1970:(1545308405 + i)];
        timeInterval = [date timeIntervalSince1970];
        strftime(buffer, sizeof(buffer), "%Y年%m月%d日%H时%M分%S秒", localtime(&timeInterval));
        string = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
    }
    CFAbsoluteTime duration = (CFAbsoluteTimeGetCurrent() - startTime) * 1000.0;
    NSLog(@"==%@", string);
    NSLog(@"\n使用C语言的方案:\n计算%ld次\n耗时%f ms\n", (long)times, duration);
}

+(NSString *)randomDateStr
{
    NSDateComponents *comp = [[NSDateComponents alloc]init];
    NSInteger year = 1800+arc4random()%300;
    NSInteger month =arc4random()%12+1;
    
    
    NSInteger day;
    NSArray * arr = @[@"1", @"3",@"5",@"7",@"8",@"10",@"12"];
    if (year%4==0 && month==2) {
        day = arc4random()%29+1;
    }else if(month==2)
    {
        day = arc4random()%28+1;
        
    }else if([arr containsObject:[NSString stringWithFormat:@"%li",month]])
    {
        day = arc4random()%31+1;
    }else
    {
        day = arc4random()%30+1;
    }
    NSInteger hour = arc4random()%23+1;
    NSInteger minute = arc4random()%59+1;
    NSInteger second = arc4random()%59+1;
    [comp setYear:year];
    [comp setMonth:month];
    [comp setDay:day];
    [comp setHour:hour];
    [comp setMinute:minute];
    [comp setSecond:second];
    
    
    NSCalendar *myCal = [[NSCalendar  alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    NSDate *myDate1 = [myCal dateFromComponents:comp];
    
    return myDate1.formatDateString;
}

@end
